﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

using ERPStore.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Exporter.Providers
{
	public class GoogleShoppingExport : ExportBase
	{
		private XDocument m_Document;
		private XElement m_Channel;

		public GoogleShoppingExport()
		{

		}

		public override void InitializeSettings(Models.Settings settings)
		{
			settings.FileName = "google_shopping.xml";
		}

		public override string Name
		{
			get { return "GoogleShopping"; }
		}

		public override string LeadSourceId
		{
			get { return "D36E99D7-CA2E-439d-B594-442D582FE118"; }
		}

		public override void CreateDocument()
		{
			m_Document = new XDocument(new XDeclaration("1.0", "UTF-8", null));
			var root = new XElement("rss"
				, new XAttribute("version", "2.0")
				, new XAttribute(XNamespace.Xmlns + "g", "http://base.google.com/ns/1.0"));

			m_Document.Add(root);

			XNamespace gns = "http://base.google.com/ns/1.0";

			m_Channel = new XElement("channel"
				, new XElement("title", "catalogue")
				, new XElement("description", "catalogue des produits")
				, new XElement("link", "http://" + GlobalConfiguration.Configuration.Settings.DefaultUrl));

			root.Add(m_Channel);
		}

		public override void AddElementToDocument(ERPStore.Models.Product product, ERPStore.Models.ProductStockInfo productStock)
		{
			// var productUrlBuilder = new ProductUrlBuilder();
			var culture = new System.Globalization.CultureInfo("en-US");
			XNamespace gns = "http://base.google.com/ns/1.0";

			var url = BuildEncryptedProductUrl(LeadSource, product);
			// productUrlBuilder.GetProductUrl(leadSource, product);
			var title = CapitalizeWords(product.PageTitle ?? product.Title);
			var mquantity = Math.Max(1, Math.Max(product.MinimumSaleQuantity, product.Packaging.Value));

			var price = product.BestPrice.ValueWithTax.ToString("#,##0.00 EUR", culture);

			var description = product.Title;
			if (product.ShortDescription != null
				&& product.ShortDescription.Length > 15)
			{
				description = product.ShortDescription;
			}

			if (product.Packaging.Value > 1)
			{
				description += string.Format(" vendu par {0}", product.Packaging.Value);
			}

			var deliveryTime = "sous 5 jours";
			var warranty = product.Warranty;
			var ecotax = (product.RecyclePrice != null) ? ToCurrency(product.RecyclePrice.ValueWithTax,true) : "";
			var deliveryCountry = GlobalConfiguration.Configuration.Settings.Shipping.DeliveryCountryList.First(i => i.Country == ERPStore.Models.Country.FRA);
			decimal deliveryCost = deliveryCountry.ShippingFeeAmount;
			if (product.Shipping.Strategy == ERPStore.Models.FeeTransportStrategy.FixedPrice)
			{
				deliveryCost = new ERPStore.Models.Price(product.Shipping.FixedPrice, product.DefaultTaxRate).ValueWithTax;
			}
			else if (product.BestPrice.Value > deliveryCountry.MinimalFreeOfCarriageAmount)
			{
				deliveryCost = 0;
			}
			string availability = null;
			if (productStock != null)
			{
				if (productStock.PhysicalStock > 0)
				{
					availability = "in stock";
				}
				else if (productStock.ProvisionnedQuantity > 0)
				{
					availability = "limited availability";
				}
				else
				{
					availability = "out of stock";
				}

				deliveryTime = string.Format("sous {0} jour{1}", productStock.DeliveryDaysCount, productStock.DeliveryDaysCount > 1 ? "s" : "");
			}

			var item = new XElement("item"
				, new XElement("title", title.RemoveIllegalXmlChar())
				, new XElement("link", url)
				, new XElement("description", description.RemoveIllegalXmlChar())
				, new XElement(gns + "id", product.Code)
				, new XElement(gns + "price", price)
				, new XElement(gns + "condition", "new")
				, new XElement(gns + "availability", availability)
				);

			if (product.Brand != null)
			{
				item.Add(new XElement(gns + "brand", product.Brand.Name));
			}

			if (product.DefaultImage != null)
			{
				var imageUrl = string.Format("http://{0}{1}", GlobalConfiguration.Configuration.Settings.DefaultUrl, string.Format(product.DefaultImage.Url, 0, 0));
				item.Add(new XElement(gns + "image_link", imageUrl));
			}

			if (product.Category != null)
			{
				var category = product.Category.GetRootProductCategory();
				item.Add(new XElement(gns + "product_type", category.Name));
			}

			if (!product.Gtin.EAN.IsNullOrTrimmedEmpty())
			{
				item.Add(new XElement(gns + "gtin", product.Gtin.EAN));
			}
			else if (!product.Gtin.UPC.IsNullOrTrimmedEmpty())
			{
				item.Add(new XElement(gns + "gtin", product.Gtin.UPC));
			}

			if (!product.ManufacturerPartNumber.IsNullOrTrimmedEmpty())
			{
				item.Add(new XElement(gns + "mpn", product.ManufacturerPartNumber));
			}

			var googledCategory = GetGoogledCategory(product.Category);
			if (googledCategory != null)
			{
				item.Add(new XElement(gns + "google_product_category", googledCategory));
			}

			if (product.StorageRank.HasValue)
			{
				item.Add(new XElement(gns + "adwords_grouping", string.Format("product_rank_{0}", product.StorageRank.Value)));
			}

			if (product.SelectedOffer != null)
			{
				item.Add(new XElement(gns + "adwords_labels", product.SelectedOffer.Name));
			}

			var shipping = new XElement(gns + "shipping",
								new XElement(gns + "country", "FR"),
								new XElement(gns + "price", string.Format("{0:F2} EUR", deliveryCost))
								);
			item.Add(shipping);

			m_Channel.Add(item);
		}

		public override void SaveDocument()
		{
			var path = Configuration.ConfigurationSettings.AppSettings["exportPath"];
			var fileName = System.IO.Path.Combine(path, Settings.FileName);

			if (System.IO.File.Exists(fileName))
			{
				System.IO.File.Delete(fileName);
			}

			var xmlSettings = new System.Xml.XmlWriterSettings()
			{
				Indent = true,
				CloseOutput = true,
				Encoding = System.Text.Encoding.UTF8,
				ConformanceLevel = System.Xml.ConformanceLevel.Document,
				CheckCharacters = false,
			};

			using (var f = System.Xml.XmlTextWriter.Create(fileName, xmlSettings))
			{
				m_Document.Save(f);
				f.Flush();
				f.Close();
			}
		}

		public override void Dispose()
		{
			m_Channel = null;
			m_Document = null;
		}

		private string GetGoogledCategory(ERPStore.Models.ProductCategory category)
		{
			if (category == null)
			{
				return null;
			}
			if (category.ExtendedProperties == null)
			{
				return GetGoogledCategory(category.Parent);
			}
			if (!category.ExtendedProperties.Any(i => i.Key.Name == "GoogleShoppingProductCategory"))
			{
				return GetGoogledCategory(category.Parent);
			}

			return category.ExtendedProperties["GoogleShoppingProductCategory"]["MappedCategoryName"];
		}

	}
}
